package com.chaber.containers.views;

import java.util.Date;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback;

import com.chaber.containers.beans.ProductCategoryData;
import com.chaber.containers.beans.ProductData;
import com.chaber.containers.common.JavaFXUtils;

import extfx.scene.control.DatePicker;

public class ProductListView extends Tab {

	//action buttons
	private Button searchButton;
	private Button clearButton;
	private Button addButton;
	
	//search fields
	private TextField brField; 
	private TextField nameField;
	private TextField amountField;
	private DatePicker cdFromField;
	private DatePicker cdToField;
	private DatePicker mdFromField; 
	private DatePicker mdToField;
	private ComboBox<ProductCategoryData> catField;

	//results table
	private TableView<ProductData> productsTable = new TableView<>();
	
	public ProductListView() {
		super("Products");

		BorderPane contentPane = new BorderPane();
		
		BorderPane searcherPanel = this.buildSearcher();
		contentPane.setTop(searcherPanel);

		this.productsTable = this.buildResultTable();
		contentPane.setBottom(this.productsTable);

		contentPane.setVisible(true);
		this.setContent(contentPane);
	}
	
	private BorderPane buildSearcher() {
		BorderPane searcherPanel = new BorderPane();

		FlowPane searcherFieldsPanel = this.buildSearcherFields();
		searcherPanel.setCenter(searcherFieldsPanel);

		HBox searcherButtonsPanel = this.buildSearcherButtons();
		searcherPanel.setBottom(searcherButtonsPanel);

		return searcherPanel;
	}

	private FlowPane buildSearcherFields() {
		FlowPane flowPane = new FlowPane();

		Label brLabel = new Label("Bar code: ");
		this.brField = new TextField(); 
		VBox brSearchField = new VBox();
		brSearchField.getChildren().addAll(brLabel, brField);
		brSearchField.setPadding(new Insets(10));
		flowPane.getChildren().add(brSearchField);

		Label nameLabel = new Label("Name: ");
		this.nameField = new TextField(); 
		VBox nameSearchField = new VBox();
		nameSearchField.getChildren().addAll(nameLabel, nameField);
		nameSearchField.setPadding(new Insets(10));
		flowPane.getChildren().add(nameSearchField);
		
		Label amountLabel = new Label("Amount: ");
		this.amountField = new TextField(); 
		this.amountField.textProperty().addListener(new ChangeListener<String>() {
			@Override
			public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
				if (newValue != null) {
					try {
						Integer.parseInt(newValue);
					} catch (NumberFormatException e) {
						amountField.setText(oldValue);
					}
				}
			}
		});
		VBox amountSearchField = new VBox();
		amountSearchField.getChildren().addAll(amountLabel, amountField);
		amountSearchField.setPadding(new Insets(10));
		flowPane.getChildren().add(amountSearchField);
		
		Label cdLabel = new Label("Creation date: ");
		Label cdFromLabel = new Label("From: ");
		this.cdFromField = new DatePicker(); 
		HBox cdFromBox = new HBox();
		cdFromBox.getChildren().addAll(cdFromLabel, this.cdFromField);
		Label cdToLabel = new Label("To: ");
		this.cdToField = new DatePicker(); 
		HBox cdToBox = new HBox();
		cdToBox.getChildren().addAll(cdToLabel, this.cdToField);
		VBox cdSearchField = new VBox();
		cdSearchField.getChildren().addAll(cdLabel, cdFromBox, cdToBox);
		cdSearchField.setPadding(new Insets(10));
		flowPane.getChildren().add(cdSearchField);
		
		Label mdLabel = new Label("Modification date: ");
		Label mdFromLabel = new Label("From: ");
		this.mdFromField = new DatePicker(); 
		HBox mdFromBox = new HBox();
		mdFromBox.getChildren().addAll(mdFromLabel, this.mdFromField);
		Label mdToLabel = new Label("To: ");
		this.mdToField = new DatePicker(); 
		HBox mdToBox = new HBox();
		mdToBox.getChildren().addAll(mdToLabel, this.mdToField);
		VBox mdSearchField = new VBox();
		mdSearchField.getChildren().addAll(mdLabel, mdFromBox, mdToBox);
		mdSearchField.setPadding(new Insets(10));
		flowPane.getChildren().add(mdSearchField);
		
		
		Label catLabel = new Label("Category: ");
		this.catField = new ComboBox<>(); 
		this.catField.setCellFactory(new Callback<ListView<ProductCategoryData>, ListCell<ProductCategoryData>>() {
			@Override
			public ListCell<ProductCategoryData> call(ListView<ProductCategoryData> arg0) {
				return JavaFXUtils.getListCell();
			}
		});
		this.catField.setButtonCell(JavaFXUtils.getListCell());
		
		VBox catSearchField = new VBox();
		catSearchField.getChildren().addAll(catLabel, catField);
		catSearchField.setPadding(new Insets(10));
		flowPane.getChildren().add(catSearchField);
		
		return flowPane;
	}

	private HBox buildSearcherButtons() {
		HBox searcherButtonsPanel = new HBox();

		this.addButton = new Button("Add new");
		searcherButtonsPanel.getChildren().add(this.addButton);
		
		this.searchButton = new Button("Search");
		searcherButtonsPanel.getChildren().add(this.searchButton);

		this.clearButton = new Button("Clear");
		searcherButtonsPanel.getChildren().add(this.clearButton);
		
		searcherButtonsPanel.setAlignment(Pos.BASELINE_RIGHT);
		searcherButtonsPanel.setSpacing(20);
		searcherButtonsPanel.setPadding(new Insets(10));

		return searcherButtonsPanel;
	}

	private TableView<ProductData> buildResultTable() {
		TableView<ProductData> productsTable = new TableView<>();

		TableColumn<ProductData, String> barcodeColumn = new TableColumn<>("Barcode");
		barcodeColumn.setCellValueFactory(new PropertyValueFactory<ProductData, String>("barCode"));

		TableColumn<ProductData, String> nameColumn = new TableColumn<>("Name");
		nameColumn.setCellValueFactory(new PropertyValueFactory<ProductData, String>("name"));

		TableColumn<ProductData, Integer> amountColumn = new TableColumn<>("Amount");
		amountColumn.setCellValueFactory(new PropertyValueFactory<ProductData, Integer>("amount"));
		
		TableColumn<ProductData, Date> creationDateColumn = new TableColumn<>("Creation date");
		creationDateColumn.setCellValueFactory(new PropertyValueFactory<ProductData, Date>("creationDate"));
		
		TableColumn<ProductData, Date> modificationDateColumn = new TableColumn<>("Modification date");
		modificationDateColumn.setCellValueFactory(new PropertyValueFactory<ProductData, Date>("modificationDate"));

		productsTable.getColumns().add(barcodeColumn);
		productsTable.getColumns().add(nameColumn);
		productsTable.getColumns().add(amountColumn);
		productsTable.getColumns().add(creationDateColumn);
		productsTable.getColumns().add(modificationDateColumn);

		productsTable.setVisible(true);
		productsTable.setEditable(false);
		productsTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
		
		return productsTable;
	}
	
	public void clearCriteria() {
		this.brField.setText(null);
		this.nameField.setText(null);
		this.amountField.setText(null);
		this.cdFromField.setValue(null);
		this.cdToField.setValue(null);
		this.mdFromField.setValue(null);
		this.mdToField.setValue(null);
		this.catField.setValue(null);
	}
	
	public ObservableList<ProductData> getProductsTableItems() {
		return productsTable.getItems();
	}

	public TextField getBrField() {
		return brField;
	}

	public void setBrField(TextField brField) {
		this.brField = brField;
	}

	public TextField getNameField() {
		return nameField;
	}

	public void setNameField(TextField nameField) {
		this.nameField = nameField;
	}

	public TextField getAmountField() {
		return amountField;
	}

	public void setAmountField(TextField amountField) {
		this.amountField = amountField;
	}

	public ComboBox<ProductCategoryData> getCatField() {
		return catField;
	}

	public void setCatField(ComboBox<ProductCategoryData> catField) {
		this.catField = catField;
	}

	public Button getSearchButton() {
		return searchButton;
	}

	public void setSearchButton(Button searchButton) {
		this.searchButton = searchButton;
	}

	public Button getClearButton() {
		return clearButton;
	}

	public void setClearButton(Button clearButton) {
		this.clearButton = clearButton;
	}

	public DatePicker getCdFromField() {
		return cdFromField;
	}

	public void setCdFromField(DatePicker cdFromField) {
		this.cdFromField = cdFromField;
	}

	public DatePicker getCdToField() {
		return cdToField;
	}

	public void setCdToField(DatePicker cdToField) {
		this.cdToField = cdToField;
	}

	public DatePicker getMdFromField() {
		return mdFromField;
	}

	public void setMdFromField(DatePicker mdFromField) {
		this.mdFromField = mdFromField;
	}

	public DatePicker getMdToField() {
		return mdToField;
	}

	public void setMdToField(DatePicker mdToField) {
		this.mdToField = mdToField;
	}

	public BorderPane getContentPane() {
		return (BorderPane) this.getContent();
	}

	public Button getAddButton() {
		return addButton;
	}

	public void setAddButton(Button addButton) {
		this.addButton = addButton;
	}

	public TableView<ProductData> getProductsTable() {
		return productsTable;
	}
}
